// 通过懒汉模式单例模式
// 需要的时候再创建
class SingletonLazy {
    private static volatile SingletonLazy instance = null;

    // 禁止外部创建对象
    private SingletonLazy() {}

    public static SingletonLazy getInstance() {
        // 再加一个判断, 防止没必要的锁竞争
        if (instance == null) { // 判断是否加锁
             synchronized (SingletonLazy.class) { // 上面条件下来后, 可能隔了一段时间才获取到锁, 这段时间可能instance已经不为空了
                 // 任何时候调用getInstance都会触发锁竞争, 影响效率
                 // 其实线程不安全只出现再首次创建对象的时候
                 if (instance == null) { // 获取到锁后, 判断是否要new对象
                     // 多线程下 是不安全的
                     // 可能多个线程同时判定 instance 为空
                     // 就会创建多个对象
                     // 加锁 保证 == 和 new 是原子性的

                     instance = new SingletonLazy();
                     // 用 volatile 修饰 instance
                     // 禁止指令重排序
                     // 加锁不能保证 new对象这个操作的原子性吗，不应该是构造完对象并且拿到地址，才会释放锁吗
                 }
             }
        }
        return instance;
    }
}
class Singleton1 {
    // 类加载的时候没有创建实例
    private static volatile Singleton1 instance = null;

    // 禁止外部创建对象
    private Singleton1() {}

    synchronized public static Singleton1 getInstance() {
        if (instance == null) {
            // 用到的时候才创建实例
            instance = new Singleton1();
        }
        return instance;
    }
}
public class ThreadDemo16 {
}
